"use client";

import React, { useCallback, useEffect, useRef, useState } from "react";
import MatrixSpectrumService from "@/src/libs/matrixSpectrumService";
import type { MatrixResult } from "@/src/libs/matrixProcessor";

const rows = 6;
const cols = 22;
const targetFps = 24; // 渲染帧率上限
const frameInterval = 1000 / targetFps;

type Props = {
  className?: string;
  onMatrixData?: (matrix: MatrixResult) => void;
  autoStart?: boolean;
};

function MatrixRenderer({
  className = "",
  onMatrixData,
  autoStart = true,
}: Props) {
  const gridRef = useRef<HTMLDivElement>(null);
  const cells2DRef = useRef<HTMLDivElement[][]>([]);
  const prevColLevelsRef = useRef<number[]>(new Array(cols).fill(0));
  const lastRenderTsRef = useRef(0);
  const pendingMatrixRef = useRef<MatrixResult | null>(null);
  const rafIdRef = useRef<number>(0);
  const serviceRef = useRef<MatrixSpectrumService | null>(null);

  const [isRunning, setIsRunning] = useState(false);
  const [statusText, setStatusText] = useState("未连接");
  const [statusOk, setStatusOk] = useState(false);
  const [gain, setGain] = useState(1.0);
  const [maxDb, setMaxDb] = useState(-20);

  const setStatus = useCallback((text: string, ok: boolean) => {
    setStatusText(text);
    setStatusOk(ok);
  }, []);

  // 初始化网格
  const initGrid = useCallback(() => {
    if (!gridRef.current) return;
    gridRef.current.innerHTML = "";
    cells2DRef.current = Array.from({ length: rows }, () => Array(cols));
    for (let r = 0; r < rows; r++) {
      for (let c = 0; c < cols; c++) {
        const cell = document.createElement("div");
        cell.className = "cell";
        gridRef.current.appendChild(cell);
        cells2DRef.current[r][c] = cell;
      }
    }
  }, []);

  // 更新单列显示
  const updateColumn = useCallback((col: number, newLevel: number) => {
    const prev = prevColLevelsRef.current[col];
    if (newLevel === prev) return;
    prevColLevelsRef.current[col] = newLevel;

    for (let r = 0; r < rows; r++) {
      const cell = cells2DRef.current[r]?.[col];
      if (cell) cell.classList.remove("on");
    }
    for (let r = rows - 1; r >= rows - newLevel; r--) {
      const cell = cells2DRef.current[r]?.[col];
      if (cell) cell.classList.add("on");
    }
  }, []);

  // 绘制一帧
  const draw = useCallback(
    (ts: number) => {
      rafIdRef.current = 0;
      if (!pendingMatrixRef.current) return;
      if (ts && ts - lastRenderTsRef.current < frameInterval) {
        rafIdRef.current = requestAnimationFrame(draw);
        return;
      }
      lastRenderTsRef.current = ts || performance.now();

      let colLevels = pendingMatrixRef.current.colLevels || [];
      // 调试：若全为 0，渲染一个测试图案以验证渲染链路
      // const nonZero = colLevels.some((v) => (v || 0) > 0);
      // if (!nonZero) {
      //   const t = (Date.now() / 1000) * 2;
      //   colLevels = Array.from({ length: cols }, (_, i) => {
      //     const s = Math.sin(t + i * 0.4);
      //     return Math.max(0, Math.min(rows, Math.round(((s + 1) / 2) * rows)));
      //   });
      // }
      // if (((Math.random() * 100) | 0) === 0) {
      //   // 间歇输出一次样本日志，避免刷屏
      //   console.log("matrixGrid colLevels sample:", colLevels.slice(0, 6));
      // }
      for (let c = 0; c < cols; c++) {
        updateColumn(c, colLevels[c] || 0);
      }
      pendingMatrixRef.current = null;
    },
    [updateColumn]
  );

  // 数据回调
  const onData = useCallback(
    (matrix: MatrixResult) => {
      pendingMatrixRef.current = matrix;
      onMatrixData?.(matrix);
      if (!rafIdRef.current) {
        rafIdRef.current = requestAnimationFrame(draw);
      }
    },
    [draw, onMatrixData]
  );

  // 启动/停止
  const handleStart = useCallback(async () => {
    try {
      if (!serviceRef.current) {
        serviceRef.current = new MatrixSpectrumService();
        serviceRef.current.onData(onData);
      }
      setStatus("连接中...", false);
      setIsRunning(true);
      await serviceRef.current.start({
        maxDb,
        gain,
        fps: targetFps,
        fftSize: 1024,
      });
      setStatus("已连接 - 正在实时分析", true);
    } catch (e: any) {
      setStatus("启动失败: " + (e?.message || String(e)), false);
      setIsRunning(false);
    }
  }, [gain, maxDb, onData, setStatus]);

  const handleStop = useCallback(async () => {
    try {
      if (serviceRef.current) {
        await serviceRef.current.stop();
      }
      setIsRunning(false);
      setStatus("未连接", false);
    } catch (e) {
      console.error("停止服务失败:", e);
    }
  }, [setStatus]);

  // 初始化与清理
  useEffect(() => {
    initGrid();
    return () => {
      if (rafIdRef.current) cancelAnimationFrame(rafIdRef.current);
      if (serviceRef.current) serviceRef.current.stop();
    };
  }, [initGrid]);

  // 自动启动
  useEffect(() => {
    if (autoStart && !isRunning) {
      // 异步触发，确保 DOM 已准备好
      const id = setTimeout(() => {
        handleStart();
      }, 0);
      return () => clearTimeout(id);
    }
  }, [autoStart, isRunning, handleStart]);

  return (
    <div className={`matrix-renderer ${className}`}>
      <div className="controls">
        {/* <button
          onClick={handleStart}
          disabled={isRunning}
          className="start-btn"
        >
          启动
        </button>
        <button onClick={handleStop} disabled={!isRunning} className="stop-btn">
          停止
        </button> */}

        <div
          className="status"
          style={{
            background: statusOk ? "rgba(16,185,129,.5)" : "rgba(239,68,68,.5)",
            color: statusOk ? "#ffffff" : "#fecaca",
          }}
        >
          {statusText}
        </div>

        <div className="sliders">
          <div className="slider-group">
            <label className="!text-black">增益: {gain.toFixed(2)}</label>
            <input
              type="range"
              min="0"
              max="200"
              value={gain * 100}
              onChange={(e) => {
                const g = Number(e.target.value) / 100;
                setGain(g);
                serviceRef.current?.setGain(g);
              }}
              className="gain-slider"
            />
          </div>

          {/* <div className="slider-group">
            <label>最大dB: {maxDb}</label>
            <input
              type="range"
              min="-60"
              max="0"
              value={maxDb}
              onChange={(e) => {
                const db = Number(e.target.value);
                setMaxDb(db);
                serviceRef.current?.setMaxDb(db);
              }}
              className="max-db-slider"
            />
          </div> */}
        </div>
      </div>

      {/* <div
        ref={gridRef}
        id="matrixGrid"
        className="matrix-grid"
        style={{
          display: "grid",
          gridTemplateColumns: `repeat(${cols}, 1fr)`,
          gridTemplateRows: `repeat(${rows}, 1fr)`,
          gap: "2px",
          width: "100%",
          height: "200px",
          backgroundColor: "#1a1a1a",
          padding: "10px",
        }}
      /> */}
    </div>
  );
}

export { MatrixRenderer };
export default MatrixRenderer;
